home *** CD-ROM | disk | FTP | other *** search
/ NOVA - For the NeXT Workstation / NOVA - For the NeXT Workstation.iso / Apps / Clocks / clocks / ClockView.m < prev    next >
Encoding:
Text File  |  1992-12-20  |  4.8 KB  |  218 lines

  1.  
  2. /* Generated by Interface Builder */
  3. /* [yeah, right, the Interface Builder generated this.  -scott] */
  4.  
  5. // My stuff.
  6. #import "ClockView.h"
  7. #import "Animator.h"
  8.  
  9. // appkit stuff.
  10. #import <appkit/nextstd.h>            // MAX()
  11. #import <appkit/Matrix.h>            // For getting the clockType.
  12.  
  13. // unix stuff.
  14. #import <math.h>                // cos, sin, M_PI
  15.  
  16. // dps stuff.
  17. #import <dpsclient/wraps.h>            // PS*().
  18.  
  19. @implementation ClockView
  20.  
  21. extern long time( long *);
  22.  
  23. + newFrame:(NXRect *)r
  24. {
  25.   self = [super newFrame:r];
  26.   [self setClockType:BEZIER];
  27.   [self setDialSize:.05];
  28.   return self;
  29. }
  30.  
  31. - free
  32. {
  33.   [animator stop:self];
  34.   [animator setTarget:nil];
  35.   return [super free];
  36. }
  37.  
  38. - takeDialSizeFrom:sender    // set the dial size via slider.
  39. {
  40.   return [self setDialSize:[sender floatValue]];
  41. }
  42. - takeClockTypeFrom:sender    // set the clock type via matrix.
  43. {
  44.   return [self setClockType:[[sender selectedCell] tag]];
  45. }
  46.  
  47. - setDialSize:(float)size    // Set programatically.
  48. {
  49.   dialSize=size;
  50.   return [self display];
  51. }
  52. - setClockType:(int)type
  53. {
  54.   clockType=type;
  55.   return [self display];
  56. }
  57.  
  58. -(int)clockType            // return the data.
  59. {
  60.   return clockType;
  61. }
  62. -(float)dialSize
  63. {
  64.   return dialSize;
  65. }
  66.  
  67. // Draws the dials in the currently focussed region, etc.  Makes little or
  68. // no sense if not used to draw in this view.  Also, won't work nicely for non-
  69. // square views.
  70. - drawDials
  71. {
  72.   float half=bounds.size.height/2.0;
  73.   float secang=sec*6*M_PI/180.0;
  74.   float minang=min*6*M_PI/180.0;
  75.   float hourang=((hour)%12)*30*M_PI/180.0+minang/12;
  76.  
  77. // define the size multiplier for each hand.
  78. #define HOUR (.4*half)
  79. #define MINUTE (.75*half)
  80. #define SECOND (.85*half)
  81.  
  82.   PSsetlinewidth( dialSize*half);
  83.   PSsetlinecap( 1);            // Rounded ends.
  84.   PSsetlinejoin( 1);            // Rounded joins.
  85.   PStranslate( half, half);
  86.   PSmoveto( sin( minang)*MINUTE, cos( minang)*MINUTE);
  87.   switch( clockType)
  88.     {
  89.       case NORMAL :            // "Normal" clock.
  90.     PSlineto( 0, 0);
  91.     PSlineto( sin( secang)*SECOND, cos( secang)*SECOND);
  92.     PSlineto( 0, 0);
  93.     PSlineto( sin( hourang)*HOUR, cos( hourang)*HOUR);
  94.         break;
  95.       case LINES :
  96.     PSlineto( sin( secang)*SECOND, cos( secang)*SECOND);
  97.     PSlineto( sin( hourang)*HOUR, cos( hourang)*HOUR);
  98.         break;
  99.       case CURVES :
  100.     PScurveto( 0, 0, 0, 0,
  101.            sin( secang)*SECOND, cos( secang)*SECOND);
  102.     PScurveto( 0, 0, 0, 0,
  103.            sin( hourang)*HOUR, cos( hourang)*HOUR);
  104.     PScurveto( 0, 0, 0, 0,
  105.            sin( minang)*MINUTE, cos( minang)*MINUTE);
  106.         break;
  107.       case BEZIER :
  108.     PScurveto( sin( secang)*SECOND, cos( secang)*SECOND,
  109.          0, 0, sin( hourang)*HOUR, cos( hourang)*HOUR);
  110.         break;
  111.     }
  112.   PSstroke();
  113.   PStranslate( -half, -half);
  114.   return self;
  115. }
  116.  
  117. - setAnimator:anObject
  118. {
  119.   if( animator==anObject)            // nip loops in the bud.
  120.     return self;
  121.   animator=anObject;
  122.   [animator setTarget:self];
  123.   [animator setTiming:1.0];
  124.   [animator setThreshold:NX_MODALRESPTHRESHOLD];    // this makes it run smoother. why?
  125.   return self;
  126. }
  127.  
  128. - animate:sender
  129. {
  130.   long clock;
  131.   struct tm *t;
  132.  
  133.   [self lockFocus];
  134.   
  135.   PSsetgray( NX_LTGRAY);        // Erase the old time.
  136.   [self drawDials];
  137.   
  138.   time( &clock);            // Snarf the new time.
  139.   t=localtime( &clock);
  140.   hour=t->tm_hour;
  141.   min=t->tm_min;
  142.   sec=t->tm_sec;
  143.   
  144.   PSsetgray( NX_BLACK);            // Draw the new time.
  145.   [self drawDials];
  146.   
  147.   [self unlockFocus];            // Make it be.
  148.   [[self window] flushWindow];
  149.   NXPing();
  150.   return self;
  151. }
  152.  
  153. - animator
  154. {
  155.   return animator;
  156. }
  157.  
  158. - drawSelf:(NXRect *)r :(int)count
  159. {
  160.   long clock;
  161.   struct tm *t;
  162.   int i;
  163.   float half=bounds.size.height/2.0;
  164. #define TICKS (.95*half)
  165.  
  166.   time( &clock);            // Snarf the time.
  167.   t=localtime( &clock);
  168.   hour=t->tm_hour;
  169.   min=t->tm_min;
  170.   sec=t->tm_sec;
  171.   
  172.   PSsetgray( NX_LTGRAY);        // Clear the background.
  173.   NXRectFill( &bounds);
  174.  
  175.   PSsetgray( NX_BLACK);            // Draw the dials.
  176.   [self drawDials];
  177.  
  178.   
  179.   PStranslate( half, half);
  180.   // Then, draw the tick marks (assume linewidth/cap set by drawDials).
  181.   PSnewpath();
  182.   for( i=0; i<12; i++, PSrotate( 30))
  183.     {
  184.       PSmoveto( TICKS, 0);
  185.       PSlineto( half, 0);
  186.     }
  187.   PSstroke();
  188.   
  189.   [[self window] flushWindow];
  190.   NXPing();
  191.   return self;
  192. }
  193.  
  194. // Here is a useful function - cut this out for your programs.  This is a Window
  195. // delegate function which keeps the window from resizing to a non-square
  196. // size.  It's not what I'd like, though - the resize bar still has that
  197. // section for resizing vertically only.  When that occurs, you do not get
  198. // to do anything.  I tried _making_ it resize, but that did not work.  So,
  199. // this is what you get.
  200. - windowWillResize:sender toSize:(NXSize *)f
  201. {
  202.   NXRect curFrame;
  203.   [sender getFrame:&curFrame];
  204.   if( curFrame.size.width==f->width || curFrame.size.height==f->height)
  205.     {
  206.       *f=curFrame.size;
  207.       return self;
  208.     }
  209.   f->width-=curFrame.size.width;
  210.   f->height-=curFrame.size.height;
  211.   f->width=f->height=MAX( f->width, f->height);
  212.   f->width+=curFrame.size.width;
  213.   f->height+=curFrame.size.height;
  214.   return self;
  215. }
  216.  
  217. @end
  218.